home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin / MIPSSIM / arith.c next >
C/C++ Source or Header  |  1999-12-02  |  10KB  |  482 lines

  1. #include "define.h"
  2.  
  3. static void ADD64(ulong a1, ulong a0,
  4.           ulong b1, ulong b0,
  5.           int cin,
  6.           ulong *s1, ulong *s0,
  7.           int *cout)
  8. {
  9.   ulong a1h,a1l;
  10.   ulong a0h,a0l;
  11.   ulong b1h,b1l;
  12.   ulong b0h,b0l;
  13.   ulong s1h,s1l;
  14.   ulong s0h,s0l;
  15.  
  16.   a1h = (a1>>16)&0xffff;
  17.   a1l = (a1    )&0xffff;
  18.   a0h = (a0>>16)&0xffff;
  19.   a0l = (a0    )&0xffff;
  20.   b1h = (b1>>16)&0xffff;
  21.   b1l = (b1    )&0xffff;
  22.   b0h = (b0>>16)&0xffff;
  23.   b0l = (b0    )&0xffff;
  24.  
  25.   s0l = a0l + b0l + cin;
  26.   s0h = a0h + b0h + ((s0l>>16)&0xffff);
  27.   s1l = a1l + b1l + ((s0h>>16)&0xffff);
  28.   s1h = a1h + b1h + ((s1l>>16)&0xffff);
  29.  
  30.   *s0 = (s0h<<16)|(s0l&0xffff);
  31.   *s1 = (s1h<<16)|(s1l&0xffff);
  32.   *cout = (s1h>>16)&1;
  33. }
  34.  
  35. void IADD64(ulong a1, ulong a0, ulong b1, ulong b0,
  36.         ulong *s1, ulong *s0, int *cy)
  37. {
  38.   ADD64(a1, a0, b1, b0, 0, s1, s0, cy);
  39. }
  40.  
  41. void ISUB64(ulong a1, ulong a0, ulong b1, ulong b0,
  42.         ulong *s1, ulong *s0, int *cy)
  43. {
  44.   ADD64(a1, a0, ~b1, ~b0, 1, s1, s0, cy);
  45. }
  46.  
  47. void NEG128(ulong a3, ulong a2, ulong a1, ulong a0,
  48.             ulong *b3, ulong *b2, ulong *b1, ulong *b0)
  49. {
  50.   int carry;
  51.   ADD64(0L, 0L, ~a1, ~a0, 1, b1, b0, &carry);
  52.   ADD64(0L, 0L, ~a3, ~a2, carry, b3, b2, &carry);
  53. }
  54.  
  55. void UMUL32(ulong a, ulong b, ulong *hi, ulong *lo)
  56. {
  57.   ulong ah,al;
  58.   ulong bh,bl;
  59.   ulong m1,m2,l;
  60.   ulong M2,M3;
  61.  
  62.   ah  = a>>16;
  63.   al  = a&0xffff;
  64.   bh  = b>>16;
  65.   bl  = b&0xffff;
  66.   l   = al*bl;
  67.   m1  = ah*bl;
  68.   m2  = al*bh;
  69.   M3  = (m1&0xffff)+(m2&0xffff) +(l>>16) ;
  70.   M2  = (M3>>16)+(m1>>16)+(m2>>16);
  71.   *lo = ((m1+m2)<<16) +l ;
  72.   *hi = M2+ah*bh;
  73. }
  74.  
  75. void UMUL64(ulong a1, ulong a0, ulong b1, ulong b0,
  76.             ulong *c3, ulong *c2, ulong *c1, ulong *c0)
  77. {
  78.   ulong a0b0_h, a0b0_l;
  79.   ulong a0b1_h, a0b1_l;
  80.   ulong a1b0_h, a1b0_l;
  81.   ulong a1b1_h, a1b1_l;
  82.   ulong tmp1_h, tmp1_l;
  83.   ulong tmp2_h, tmp2_l;
  84.   ulong tmp3_h, tmp3_l;
  85.   ulong tmp;
  86.   int   cy0,cy1,cy2;
  87.  
  88.   UMUL32(a0, b0, &a0b0_h, &a0b0_l);
  89.   UMUL32(a0, b1, &a0b1_h, &a0b1_l);
  90.   UMUL32(a1, b0, &a1b0_h, &a1b0_l);
  91.   UMUL32(a1, b1, &a1b1_h, &a1b1_l);
  92.   ADD64(0,      a0b0_h, a0b1_h, a0b1_l, 0, &tmp1_h, &tmp1_l, &cy0);
  93.   ADD64(tmp1_h, tmp1_l, a1b0_h, a1b0_l, 0, &tmp2_h, &tmp2_l, &cy1);
  94.   tmp = cy0+cy1;
  95.   ADD64(tmp,    tmp2_h, a1b1_h, a1b1_l, 0, &tmp3_h, &tmp3_l, &cy2);
  96.   *c0 = a0b0_l;
  97.   *c1 = tmp2_l;
  98.   *c2 = tmp3_l;
  99.   *c3 = tmp3_h;
  100. }
  101.  
  102. void UDIV64(ulong sh, ulong sl, ulong th, ulong tl,
  103.             ulong *qh, ulong *ql, ulong *rh, ulong *rl)
  104. {
  105.   int   i;
  106.   int   carry,carry2;
  107.   ulong q_h, q_l, r_h, r_l;
  108.   q_h = 0L;
  109.   q_l = 0L;
  110.   for(i=0;i<64;i++){
  111.     ADD64(sh, sl, sh, sl, 0, &r_h, &r_l, &carry2);
  112.     sh = r_h;
  113.     sl = r_l;
  114.     ADD64(q_h, q_l, q_h, q_l, 0, &r_h, &r_l, &carry);
  115.     q_h = r_h;
  116.     q_l = r_l|carry2;
  117.     ADD64(q_h, q_l, ~th, ~tl, 1, &r_h, &r_l, &carry);
  118.     if(carry){ /* not borrow */
  119.       sl |= 1;
  120.       q_h = r_h;
  121.       q_l = r_l;
  122.     }
  123.   }
  124.   *qh = sh;
  125.   *ql = sl;
  126.   *rh = q_h;
  127.   *rl = q_l;
  128. }
  129.  
  130. void UDIV32(ulong s, ulong t, ulong *q, ulong *r)
  131. {
  132.   int   i;
  133.   int   carry;
  134.   ulong q_l, r_h, r_l;
  135.  
  136.   q_l = 0L;
  137.   for(i=0;i<32;i++){
  138.     ADD64(q_l, s, q_l, s, 0, &r_h, &r_l, &carry);
  139.     q_l = r_h;
  140.     s   = r_l;
  141.     ADD64(0, q_l, 0xffffffffL, ~t, 1, &r_h, &r_l, &carry);
  142.     if(carry){ /* not borrow */
  143.       s  |= 1;
  144.       q_l = r_l;
  145.     }
  146.   }
  147.   *q = s;
  148.   *r = q_l;
  149. }
  150.  
  151. void FDIV64(ulong sh, ulong sl, ulong th, ulong tl,
  152.             ulong *qh, ulong *ql, ulong *rh, ulong *rl,
  153.         int cnt)
  154. {
  155.   int   i;
  156.   int   carry;
  157.   ulong q_h, q_l, r_h, r_l;
  158.  
  159.   q_h = 0L;
  160.   q_l = 0L;
  161.   for(i=0;i<cnt;i++){
  162.     ADD64(sh, sl, ~th, ~tl, 1, &r_h, &r_l, &carry);
  163.     if(carry){ /* not borrow */
  164.       q_l |= 1;
  165.       sh = r_h;
  166.       sl = r_l;
  167.     }
  168.     ADD64(sh, sl, sh, sl, 0, &r_h, &r_l, &carry);
  169.     sh = r_h;
  170.     sl = r_l;
  171.     ADD64(q_h, q_l, q_h, q_l, 0, &r_h, &r_l, &carry);
  172.     q_h = r_h;
  173.     q_l = r_l;
  174.   }
  175.   *qh = q_h;
  176.   *ql = q_l;
  177.   *rh = sh;
  178.   *rl = sl;
  179. }
  180.  
  181. void FSQRT64(ulong x1, ulong x0, ulong *y1, ulong *y0, ulong *r)
  182. {
  183.   int i,d;
  184.   ulong q1, q0, b1, b0, a1, a0, s1, s0, t1, t0;
  185.  
  186.   a1 = 0;
  187.   a0 = 0;
  188.   b1 = 0;
  189.   b0 = 0;
  190.   q1 = 0;
  191.   q0 = 0;
  192.   for(i=0;i<56;i++){
  193.     s1 = 0;
  194.     s0 = (x1>>23)&3;
  195.     ADD64(a1, a0, s1, s0, 0, &t1, &t0, &d);
  196.     a1 = t1;
  197.     a0 = t0;
  198.     ADD64(b1, b0, 0, 1, 0, &s1, &s0, &d);/* b+1 */
  199.     ADD64(a1, a0, ~s1, ~s0, 1, &t1, &t0, &d); /* t=a-(b+1) */
  200.     if(d){ /* not borrow */
  201.       q0 = q0+1;
  202.       a1 = t1;
  203.       a0 = t0;
  204.       ADD64(b1, b0, 0, 2, 0, &t1, &t0, &d); /* b+2 */
  205.       b1 = t1;
  206.       b0 = t0;
  207.     }
  208.     b1 = (b1<<1)|(b0>>31);
  209.     b0 = b0<<1;
  210.     q1 = (q1<<1)|(q0>>31);
  211.     q0 = q0<<1;
  212.     a1 = (a1<<2)|(a0>>30);
  213.     a0 = a0<<2;
  214.     x1 = (x1<<2)|(x0>>30);
  215.     x0 = x0<<2;
  216.   }
  217.   *y1=q1;
  218.   *y0=q0;
  219.   *r =(a1|a0);
  220. }
  221.  
  222. void FSQRT32(ulong s, ulong *d, ulong *r)
  223. {
  224.   int i;
  225.   int q,a,b;
  226.  
  227.   a=0;
  228.   b=0;
  229.   q=0;
  230.   for(i=0;i<27;i++){
  231.     a += (s>>26)&3;
  232.     if((a-(b+1))>=0){
  233.       q=q+1;
  234.       a=a-(b+1);
  235.       b=b+2;
  236.     }
  237.     b=b<<1;
  238.     q=q<<1;
  239.     a=a<<2;
  240.     s=s<<2;
  241.   }
  242.   *d=q;
  243.   *r=a;
  244. }
  245.  
  246. void RSHIFTS(ulong ihi, ulong ilo, int cnt,
  247.              ulong *ohi, ulong *olo)
  248. {
  249.   ulong msk;
  250.  
  251.   if(cnt>=64){
  252.     *ohi = 0L;
  253.     *olo = ((ihi|ilo)!=0);
  254.   }
  255.   else if(cnt>=32){
  256.     msk  = (1<<(cnt-32))-1;
  257.     *ohi = 0L;
  258.     *olo = (ihi>>(cnt-32))|((ihi&msk)!=0)|(ilo!=0);
  259.   }
  260.   else if(cnt==0){
  261.     *ohi = ihi;
  262.     *olo = ilo;
  263.   }
  264.   else{
  265.     msk  = (1<<cnt)-1;
  266.     *ohi = (ihi>>cnt);
  267.     *olo = (ihi<<(32-cnt))|(ilo>>cnt)|((ilo&msk)!=0);
  268.   }
  269. }
  270.  
  271. void RSHIFTL(ulong ihi, ulong ilo, int cnt,
  272.             ulong *ohi, ulong *olo)
  273. {
  274.   if(cnt>=64){
  275.     *ohi = 0L;
  276.     *olo = 0L;
  277.   }
  278.   else if(cnt>=32){
  279.     *ohi = 0;
  280.     *olo = (ihi>>(cnt-32));
  281.   }
  282.   else if(cnt==0){
  283.     *ohi = ihi;
  284.     *olo = ilo;
  285.   }
  286.   else{
  287.     *ohi = (ihi>>cnt);
  288.     *olo = (ihi<<(32-cnt))|(ilo>>cnt);
  289.   }
  290. }
  291.  
  292. void RSHIFTA(ulong ihi, ulong ilo, int cnt,
  293.             ulong *ohi, ulong *olo)
  294. {
  295.   int sgn;
  296.  
  297.   sgn = ((ihi&0x80000000L)!=0);
  298.  
  299.   if(cnt>=64){
  300.     *ohi = (sgn)? 0xffffffffL : 0L;
  301.     *olo = (sgn)? 0xffffffffL : 0L;
  302.   }
  303.   else if(cnt>=32){
  304.     *ohi = (sgn)? 0xffffffffL : 0L;
  305.     *olo = (((long)ihi)>>(cnt-32));
  306.   }
  307.   else if(cnt==0){
  308.     *ohi = ihi;
  309.     *olo = ilo;
  310.   }
  311.   else{
  312.     *ohi = (((long)ihi)>>cnt);
  313.     *olo = (ihi<<(32-cnt))|(ilo>>cnt);
  314.   }
  315. }
  316.  
  317. void LSHIFT(ulong ihi, ulong ilo, int cnt,
  318.             ulong *ohi, ulong *omd, ulong *olo)
  319. {
  320.   if(cnt>=96){
  321.     *ohi = 0L;
  322.     *omd = 0L;
  323.     *olo = 0L;
  324.   }
  325.   else if(cnt>=64){
  326.     *ohi = ilo << (cnt-64);
  327.     *omd = 0L;
  328.     *olo = 0L;
  329.   }
  330.   else if(cnt>32){
  331.     *ohi = (ihi<<(cnt-32))|(ilo>>(64-cnt));
  332.     *omd = (ilo<<(cnt-32));
  333.     *olo = 0L;
  334.   }
  335.   else if(cnt==32){
  336.     *ohi = ihi;
  337.     *omd = ilo;
  338.     *olo = 0L;
  339.   }
  340.   else if(cnt==0){
  341.     *ohi = 0L;
  342.     *omd = ihi;
  343.     *olo = ilo;
  344.   }
  345.   else{
  346.     *ohi = (ihi>>(32-cnt));
  347.     *omd = (ihi<<cnt)|(ilo>>(32-cnt));
  348.     *olo = (ilo<<cnt);
  349.   }
  350. }
  351.  
  352. int CLZ32(ulong a)
  353. {
  354.   return ((a&0xffffffffL)==0)? 32:
  355.          ((a&0xfffffffeL)==0)? 31:
  356.          ((a&0xfffffffcL)==0)? 30:
  357.          ((a&0xfffffff8L)==0)? 29:
  358.          ((a&0xfffffff0L)==0)? 28:
  359.          ((a&0xffffffe0L)==0)? 27:
  360.          ((a&0xffffffc0L)==0)? 26:
  361.          ((a&0xffffff80L)==0)? 25:
  362.          ((a&0xffffff00L)==0)? 24:
  363.          ((a&0xfffffe00L)==0)? 23:
  364.          ((a&0xfffffc00L)==0)? 22:
  365.          ((a&0xfffff800L)==0)? 21:
  366.          ((a&0xfffff000L)==0)? 20:
  367.          ((a&0xffffe000L)==0)? 19:
  368.          ((a&0xffffc000L)==0)? 18:
  369.          ((a&0xffff8000L)==0)? 17:
  370.          ((a&0xffff0000L)==0)? 16:
  371.          ((a&0xfffe0000L)==0)? 15:
  372.          ((a&0xfffc0000L)==0)? 14:
  373.          ((a&0xfff80000L)==0)? 13:
  374.          ((a&0xfff00000L)==0)? 12:
  375.          ((a&0xffe00000L)==0)? 11:
  376.          ((a&0xffc00000L)==0)? 10:
  377.          ((a&0xff800000L)==0)?  9:
  378.          ((a&0xff000000L)==0)?  8:
  379.          ((a&0xfe000000L)==0)?  7:
  380.          ((a&0xfc000000L)==0)?  6:
  381.          ((a&0xf8000000L)==0)?  5:
  382.          ((a&0xf0000000L)==0)?  4:
  383.          ((a&0xe0000000L)==0)?  3:
  384.          ((a&0xc0000000L)==0)?  2:
  385.          ((a&0x80000000L)==0)?  1:
  386.          0;
  387. }
  388.  
  389. int CLZ64(ulong ah, ulong al)
  390. {
  391.   int clz;
  392.  
  393.   clz = CLZ32(ah);
  394.   if(clz<32)
  395.     return clz;
  396.   clz = CLZ32(al);
  397.   return clz+32;
  398. }
  399.  
  400. int CLO32(ulong a)
  401. {
  402.   return CLZ32(~a);
  403. }
  404.  
  405. int CLO64(ulong ah, ulong al)
  406. {
  407.   return CLZ64(~ah, ~al);
  408. }
  409.  
  410. void CMP64(ulong sh, ulong sl, ulong th, ulong tl, int *lt, int *eq)
  411. {
  412.   int   s, t, cy;
  413.   ulong dh, dl;
  414.  
  415.   s = ((sh&0x80000000L)!=0L);
  416.   t = ((th&0x80000000L)!=0L);
  417.  
  418.   *eq = (sh==th)&&(sl==tl);
  419.   if((s)&&(!t)){
  420.     *lt = 1;
  421.   }
  422.   else if((!s)&&(t)){
  423.     *lt = 0;
  424.   }
  425.   else{
  426.     ISUB64(sh, sl, th, tl, &dh, &dl, &cy);
  427.     *lt = ((dh&0x80000000L)!=0L);
  428.   }
  429. }
  430.  
  431. void ACMP64(ulong sh, ulong sl, ulong th, ulong tl, int *lt, int *eq)
  432. {
  433.   int   s, t, e, cy;
  434.   ulong dh, dl;
  435.  
  436.   s = ((sh&0x80000000L)!=0L);
  437.   t = ((th&0x80000000L)!=0L);
  438.  
  439.   e = (sh==th)&&(sl==tl);
  440.   *eq = e;
  441.   if((s)&&(!t)){
  442.     *lt = 1;
  443.   }
  444.   else if((!s)&&(t)){
  445.     *lt = 0;
  446.   }
  447.   else{
  448.     ISUB64(sh, sl, th, tl, &dh, &dl, &cy);
  449.     if(s&&t)
  450.       *lt = (cy&&(!e));
  451.     else
  452.       *lt = ((!cy)&&(!e));
  453.   }
  454. }
  455.  
  456. void UCMP64(ulong sh, ulong sl, ulong th, ulong tl, int *lt, int *eq)
  457. {
  458.   int   cy;
  459.   ulong dh, dl;
  460.  
  461.   *eq = (sh==th)&&(sl==tl);
  462.   ISUB64(sh, sl, th, tl, &dh, &dl, &cy);
  463.   *lt = (!cy);
  464. }
  465.  
  466. void INEG64(ulong sh, ulong sl, ulong *dh, ulong *dl)
  467. {
  468.   int cy;
  469.   ISUB64(0L, 0L, sh, sl, dh, dl, &cy);
  470. }
  471.  
  472. void IADD96(ulong s2, ulong s1, ulong s0,
  473.             ulong t2, ulong t1, ulong t0,
  474.             ulong *d2, ulong *d1, ulong *d0)
  475. {
  476.   int cy;
  477.  
  478.   ADD64(s1, s0, t1, t0, 0, d1, d0, &cy);
  479.   *d2 = s2+t2+(ulong)cy;
  480. }
  481.  
  482.